package com.staryy.activiti7_workflow.controller;


import com.staryy.activiti7_workflow.SecurityUtil;
import com.staryy.activiti7_workflow.mapper.ActivitiMapper;
import com.staryy.activiti7_workflow.util.AjaxResponse;
import com.staryy.activiti7_workflow.util.GlobalConfig;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.FormProperty;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 任务接口
 */
@RestController
@RequestMapping("/task")
public class TaskController {

    @Autowired
    private TaskRuntime taskRuntime;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private ProcessRuntime processRuntime;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ActivitiMapper activitiMapper;

    /**
     * 查询待办任务
     *
     * @return
     */
    @GetMapping("/getTasks")
    public AjaxResponse getTasks() {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            List<Map<String, Object>> mapList = new ArrayList<>();
            Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 100));
            List<Task> taskList = taskPage.getContent();
            for (Task task : taskList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", task.getId());
                map.put("name", task.getName());
                map.put("status", task.getStatus());
                map.put("createdDate", task.getCreatedDate());
                if (StringUtils.isBlank(task.getAssignee())) {
                    map.put("assignee", "任务待拾取");
                } else {
                    map.put("assignee", task.getAssignee());
                }
                ProcessInstance instance = processRuntime.processInstance(task.getProcessInstanceId());
                map.put("instanceId", task.getProcessInstanceId());
                map.put("instanceName", instance.getName());

                mapList.add(map);
            }
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), mapList);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(), "查询待办任务失败", e.toString());
        }
    }


    /**
     * 完成任务
     *
     * @return
     */
    @GetMapping("/completeTask")
    public AjaxResponse completeTask(@RequestParam("taskId") String taskId) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            Task task = taskRuntime.task(taskId);
            // 办理人为空表示当前登录用户为候选人，需先拾取任务后再完成任务
            if (task.getAssignee() == null) {
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
            }
            taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), task.getStatus());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(), "完成任务失败", e.toString());
        }
    }


    /**
     * 任务表单渲染
     *
     * @return
     */
    @GetMapping("/formDataShow")
    public AjaxResponse formDataShow(@RequestParam("taskId") String taskId) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            Task task = taskRuntime.task(taskId);
            UserTask userTask = (UserTask) repositoryService.getBpmnModel(task.getProcessDefinitionId()).getFlowElement(task.getFormKey());
            if (userTask == null) {
                return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), "无表单");
            }
            List<Map<String,Object>> mapList = new ArrayList<>();
            List<FormProperty> formProperties = userTask.getFormProperties();
            for(FormProperty property : formProperties){
                Map<String,Object> map = new HashMap<>();
                String propertyId = property.getId();
                String[] items = propertyId.split("-_!");
                map.put("id",items[0]);
                map.put("controlType",items[1]);
                map.put("controlLabel",items[2]);
                map.put("controlDefValue",items[3]);
                map.put("controlParam",items[4]);
                mapList.add(map);
            }
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), mapList);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(), "任务表单渲染失败", e.toString());
        }
    }

    /**
     * 任务表单保存
     *
     * @return
     */
    @GetMapping("/formDataSave")
    public AjaxResponse formDataSave(@RequestParam("taskId") String taskId,
                                     @RequestParam("formDataString") String formDataString) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            List<HashMap<String,Object>> mapList = new ArrayList<>();
            Map<String,Object> variables = new HashMap<>();
            Task task = taskRuntime.task(taskId);
            String[] controlList = formDataString.split("!_!");
            for(String con : controlList){
                HashMap<String,Object> map = new HashMap<>();
                String[] items = con.split("-_!");
                map.put("CONTROL_ID_",items[0]);
                map.put("CONTROL_VALUE_",items[1]);
                // map.put("CONTROL_PARAM_",items[2]);
                map.put("PROC_DEF_ID_",task.getProcessDefinitionId());
                map.put("PROC_INST_ID_",task.getProcessInstanceId());
                map.put("FORM_KEY_",task.getFormKey());
                mapList.add(map);

                switch (items[2]){
                    case "f":
                        System.out.println("空间值不作为参数");
                        break;
                    case "s":
                        variables.put(items[0],items[1]);
                        break;
                    case "t":
                        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm");
                        variables.put(items[0],sdf.parse(items[1]));
                        break;
                    case "b":
                        variables.put(items[0], BooleanUtils.toBoolean(items[1]));
                        break;
                }
            }
            if(!variables.isEmpty()){
                taskRuntime.complete(TaskPayloadBuilder.complete()
                        .withTaskId(taskId)
                        .withVariables(variables)
                        .build());
            }else{
                taskRuntime.complete(TaskPayloadBuilder.complete()
                        .withTaskId(taskId)
                        .build());
            }
            int i = activitiMapper.insertFormData(mapList);
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(), GlobalConfig.ResponseCode.SUCCESS.getDesc(), i);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(), "任务表单保存失败", e.toString());
        }
    }
}
